#pragma once


#include <opencv2/opencv.hpp> 
using namespace cv;


Point sp(-1, -1);
Point ep(-1, -1);
Mat tempimage;
std::string mousedraw = "鼠标绘制";


/// <summary>
/// 鼠标操作具体函数  该函数参数是确定的
/// </summary>
/// <param name="event">鼠标事件  为枚举值 具体查看API</param>
/// <param name="x">系统捕获的鼠标实时x位置</param>
/// <param name="y">系统捕获的鼠标实时y位置</param>
/// <param name="flags"></param>
/// <param name="userdata">传入的图像等信息</param>
static void on_draw(int event, int x, int y, int flags, void* userdata)
{
	Mat image = *((Mat*)userdata);
	int imageWidth = image.cols;
	int imageHeight = image.rows;
	//鼠标左键按下时动作   将按下xy位置传给起始点
	if (event == EVENT_LBUTTONDOWN)
	{
		sp.x = x;
		sp.y = y;
		std::cout << "st p" << sp << std::endl;
	}
	else if (event == EVENT_LBUTTONUP)//鼠标左键放开时动作   将放开时的xy位置传给终点 并进行后续操作
	{
		ep.x = x;
		ep.y = y;
		if (x > imageWidth)
		{
			ep.x = imageWidth - 1;
		}
		if (y > imageHeight)
		{
			ep.y = imageHeight - 1;
		}
		int dx = ep.x - sp.x;
		int dy = ep.y - sp.y;
		//若鼠标点击是从左上画到右下 则绘制矩形
		if (dx > 0 && dy > 0)
		{

			//定义矩形框 
			Rect box(sp.x, sp.y, dx, dy);
			//将框出的矩形内的image图像的一部分取出来  取之前使用原图备份保证取得源数据的纯净
			tempimage.copyTo(image);
			imshow("ROI区域", image(box));

			//开始绘制矩形
			rectangle(image, box, Scalar(0, 255, 200), 2, 8, 0);
			imshow(mousedraw, image);	//刷新当前图像 

			//矩形绘制完成后 需要将起点归位 
			sp.x = -1;
			sp.y = -1;
		}
		std::cout << "dx =" << dx << "\tdy=" << dy << std::endl;

	}
	else if (event == EVENT_MOUSEMOVE) //此处用于点击了起点后 未点击重点 鼠标处于移动时 可以 实时看到矩形框
	{
		//当在图面上点了起点
		if (sp.x > 0 || sp.y > 0)
		{
			//当前移动到的鼠标位置传给终点 
			ep.x = x;
			ep.y = y;
			if (x > imageWidth)
			{
				ep.x = imageWidth - 1;
			}
			if (y > imageHeight)
			{
				ep.y = imageHeight - 1;
			}
			int dx = ep.x - sp.x;
			int dy = ep.y - sp.y;
			//若鼠标点击是从左上画到右下 则绘制矩形
			if (dx > 0 && dy > 0)
			{
				//定义绘制矩形
				Rect box(sp.x, sp.y, dx, dy);
				//将原图tempimage拷贝到当前显示的图面 将移动检测时绘制的矩形刷掉 
				//则能够保证每次检测鼠标移动时绘制矩形前，图面干净
				tempimage.copyTo(image);
				//image上绘制矩形
				rectangle(image, box, Scalar(0, 255, 200), 2, 8, 0);
				//刷新图面image
				imshow(mousedraw, image);
			}
		}
	}

}

/// <summary>
/// 鼠标事件方法入口
/// </summary>
/// <param name="image"></param>
void mouse_event_demo(Mat& image)
{
	//将原图拷贝一份独立内存，作为原图备份
	tempimage = image.clone();
	namedWindow(mousedraw, WINDOW_AUTOSIZE);
	//鼠标的响应函数
	setMouseCallback(mousedraw, on_draw, (void*)(&image));
	//初始化图面显示
	imshow(mousedraw, image);
}
